package com.xdap.pg.exam.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.definesys.mpaas.common.exception.MpaasBusinessException;
import com.xdap.motor.utils.StringUtils;
import com.xdap.pg.exam.dao.ExamDao;
import com.xdap.pg.exam.dto.ExamQuestionDto;
import com.xdap.pg.exam.entity.*;
import com.xdap.pg.exam.response.Response;
import com.xdap.pg.exam.utils.PGUtils;
import com.xdap.pg.exam.vo.CheckQuestionsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ExamService {

    @Autowired
    ExamDao examDao;

    @Resource DataService dataService;
    public static final String ANNUALLY = "[\"Annually\"]";

    public Response extractQuestions(final ExamQuestionDto examQuestionDto) {
        log.info("examQuestionDto对象：{}", JSON.toJSONString(examQuestionDto));
        Response<Map<String,Object>> response = new Response();
        final String versionId = dataService.getVersionSelectId(examQuestionDto);
        List<String> areas = examQuestionDto.getArea();
        if (areas.contains("不限")) {
            areas = null;
        }
        final String siteId = dataService.getSiteNameSelectId(examQuestionDto);
        final int qualityCount = examQuestionDto.getQuality();
        final int stewardshipCount = examQuestionDto.getStewardship();
        List<ItemBank> itemBanks = dataService.getItemBank(siteId,areas, versionId);
        // 根据类型对查询到到题库进行分组Quality/Stewardship
        Map<String,List<ItemBank>> itemBankMap = itemBanks.stream().collect(Collectors.groupingBy(ItemBank::getItemType));
        List<ItemBank> qualityItemBanks = itemBankMap.get("[\"Quality\"]");
        List<ItemBank> stewardshipItemBanks = itemBankMap.get("[\"Stewardship\"]");

        List<ItemBank> returnQualityItemBanks = getItemBanks(qualityItemBanks, qualityCount);
        List<ItemBank> returnStewardshipItemBanks = getItemBanks(stewardshipItemBanks, stewardshipCount);

        response.setCode("ok");
        response.setMessage("抽题成功");
        Map<String, Object> resultMap = new HashMap<>();

        resultMap.put("quality",returnQualityItemBanks);
        resultMap.put("stewardship",returnStewardshipItemBanks);

        List<ItemBank> paperItems = dataService.getYesItemBanks(siteId, versionId);
        List<ItemBank> itemBankss = dataService.getAllItemBanks(siteId, versionId);
        log.info("个数 paperItems：{}",paperItems.size());
        log.info("抽题总数-个数 itemBankss：{}",itemBankss.size());
        //Quality 已完成 抽题的数量, 总数量
        Long qualityFinishedCount = Optional.ofNullable(paperItems).orElseGet(ArrayList::new).stream().filter(item -> item.getItemType().equals("Quality")).count();
        Long qualityAllCount = Optional.ofNullable(itemBankss).orElseGet(ArrayList::new).stream().filter(item -> item.getItemType().equals("Quality")).count();
        log.info("个数：qualityFinishedCount：{},qualityAllCount:{}",qualityFinishedCount,qualityAllCount);
        float qualityQuestionRate = ((qualityFinishedCount + returnQualityItemBanks.size()) / Float.valueOf(String.valueOf(qualityAllCount))) * 100;

        //Stewardship 已完成 抽题的数量, 总数量
        Long stewardshipFinishedCount = Optional.ofNullable(paperItems).orElseGet(ArrayList::new).stream().filter(item -> item.getItemType().equals("Stewardship")).count();
        Long stewardshipAllCount = Optional.ofNullable(itemBankss).orElseGet(ArrayList::new).stream().filter(item -> item.getItemType().equals("Stewardship")).count();
        log.info("个数：stewardshipFinishedCount：{},stewardshipAllCount:{}",stewardshipFinishedCount,stewardshipAllCount);
        float stewardshipQuestionRate = ((stewardshipFinishedCount + returnStewardshipItemBanks.size()) / Float.valueOf(String.valueOf(stewardshipAllCount))) * 100;

        resultMap.put("qualityQuestionRate",String.format("%.2f", qualityQuestionRate));
        resultMap.put("stewardshipQuestionRate",String.format("%.2f", stewardshipQuestionRate));
        response.setData(resultMap);
        return response;
    }

    private List<ItemBank> getItemBanks(List<ItemBank> itemBanks, int questionCount) {
        List<ItemBank> returnItemBanks = new ArrayList<>();
        if (questionCount > 0 ) {
            //首先按季度抽一次,对结果进行随机排序
            List<ItemBank> questions = Optional.ofNullable(itemBanks).orElseGet(ArrayList::new).stream().filter(bank -> StringUtils.isNotBlank(bank.getItemFrequency()) && bank.getItemFrequency().equalsIgnoreCase(PGUtils.getCurrentQuarterIndex())).collect(Collectors.toList());
            if (Objects.nonNull(questions) && !questions.isEmpty()) {
                Collections.shuffle(questions);
                returnItemBanks.addAll(questions.stream().skip(0).limit(questionCount).collect(Collectors.toList()));
            }
            int readyCount = returnItemBanks.size();
            if (readyCount < questionCount) {
                questions = Optional.ofNullable(itemBanks).orElseGet(ArrayList::new).stream().filter(bank -> StringUtils.isNotBlank(bank.getItemFrequency()) && bank.getItemFrequency().equalsIgnoreCase(PGUtils.getCurrentYearIndex())).collect(Collectors.toList());
                if (Objects.nonNull(questions) && !questions.isEmpty()) {
                    Collections.shuffle(questions);
                    returnItemBanks.addAll(questions.stream().skip(0).limit(questionCount - readyCount).collect(Collectors.toList()));
                }
            }
            readyCount = returnItemBanks.size();
            if (readyCount < questionCount) {
                questions = Optional.ofNullable(itemBanks).orElseGet(ArrayList::new).stream().filter(bank -> StringUtils.isNotBlank(bank.getItemFrequency()) && bank.getItemFrequency().equalsIgnoreCase(ANNUALLY)).collect(Collectors.toList());
                if (Objects.nonNull(questions) && !questions.isEmpty()) {
                    Collections.shuffle(questions);
                    returnItemBanks.addAll(questions.stream().skip(0).limit(questionCount - readyCount).collect(Collectors.toList()));
                }
            }
            Optional.ofNullable(returnItemBanks).orElseGet(ArrayList::new).stream().forEach(itemBank -> {
                itemBank.setItemType(itemBank.getItemType().replace("\\","").replace("[\"","").replace("\"]",""));
                itemBank.setItemGroup(itemBank.getItemGroup().replace("\\","").replace("[\"","").replace("\"]",""));
                itemBank.setItemFrequency(StringUtils.isNotBlank(itemBank.getItemFrequency()) ? itemBank.getItemFrequency().replace("\\","").replace("[\"","").replace("\"]","") : StringUtils.EMPTY);
                itemBank.setItemIsfinished(itemBank.getItemIsfinished().replace("\\","").replace("[\"","").replace("\"]",""));
                itemBank.setItemSite(itemBank.getItemSite().replace("\\","").replace("[\"","").replace("\"]",""));
                itemBank.setItemArea(itemBank.getItemArea().replace("\\","").replace("[\"","").replace("\"]",""));
                itemBank.setItemVersion(itemBank.getItemVersion().replace("\\","").replace("[\"","").replace("\"]",""));
            });
        }
        return returnItemBanks;
    }

    public com.definesys.mpaas.common.http.Response checkSubmitQuestions( CheckQuestionsVo checkQuestionsVo){
        log.info("校验题目提交入参："+ JSONObject.toJSONString(checkQuestionsVo));
        List<String> questionsCode = checkQuestionsVo.getQuestionsList();
        if (CollectionUtils.isEmpty(questionsCode)) {
            log.error("传过来的值转换的对象为空，请检查");
            throw new MpaasBusinessException("传过来的值转换的对象为空，请检查");
        }
        List<Map<String,Object>> itemBanks = examDao.queryItemBank(questionsCode);
        log.info("查询题库："+ JSONObject.toJSONString(itemBanks));
        if(CollectionUtils.isEmpty(itemBanks)){
            return com.definesys.mpaas.common.http.Response.ok();
        }else {
            StringBuffer sb=new StringBuffer();
            itemBanks.forEach(itemBank->{sb.append(itemBank.get("Code")+",");});
            return com.definesys.mpaas.common.http.Response.error(sb+"题目已完成，请检查后重新提交");
        }


    }
}
